from typing import Union, Any, Dict, List, Tuple
from ..schemas import Message
import json

# Type definitions
JsonDict = Dict[str, Any]
EMPTY_JSON_VALUES = ('', '{}')

def parse_json(json_str: Union[str, Any], type: str="output") -> Union[JsonDict, None]:
    """
    Validate a JSON string, handling edge cases and returning an empty dict for invalid inputs/output arguments.
    
    Args:
        json_str: String containing JSON or any other value
        type: String input or output
        
    Returns:
        Parsed JSON dict or None if parsing fails
    """
    # Handle non-string inputs
    if not isinstance(json_str, str):
        if type == "output":
            return None
        else:
            return {}
    
    # Handle empty inputs
    json_str = json_str.strip()
    if not json_str or json_str in EMPTY_JSON_VALUES:
        if type == "output":
            return None
        else:
            return {}
    
    # Attempt to parse
    try:
        return json.loads(json_str)
    except json.JSONDecodeError:
        if type == "output":
            return None
        else:
            return {}

def parse_json_safely(json_str: Union[str, Any]) -> JsonDict:
    """
    Parse a JSON string safely, handling edge cases and returning an empty dict for invalid inputs.
    
    Args:
        json_str: String containing JSON or any other value
        
    Returns:
        Parsed JSON dict or empty dict if parsing fails
    """
    return parse_json(json_str, type="input")

def format_conversation(messages: List[Message], provider: str)->List[Dict]:
    result = []
    for message in messages:
        # Unified to current provider
        if message.role == "tool":
            message.provider = provider
        result.append(message.get_message())
    
    return result


def parse_content(content: str)-> Tuple[str,str]:
        start=content.find(f"<think>")
        end=content.find(f"</think>")
        thinking=""
        assistant_text=""
        if start !=-1 and end !=-1:
            thinking=content[start+7:end].strip()
            assistant_text=content[end+8:].strip()
        else:
           assistant_text=content.strip() 
        return thinking, assistant_text